package com.tanhua.app.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tanhua.api.*;
import com.tanhua.app.interceptor.UserHolder;
import com.tanhua.commons.utils.Constants;
import com.tanhua.config.template.HuanXinTemplate;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.pojo.Question;
import com.tanhua.model.pojo.UserInfo;
import com.tanhua.model.vo.NearUserVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class TanhuaService {
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private MessagesService messagesService;
    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private QuestionApi questionApi;
    @DubboReference
    private UserLikeApi userLikeApi;
    @DubboReference
    private FriendApi friendApi;
    @DubboReference
    private UserLocationApi userLocationApi;
    @DubboReference
    private VisitorsApi visitorsApi;


    //查询今日佳人
    public TodayBest todayBest() {
        //1 查询缘分值最高的推荐用户
        RecommendUser recommendUser = recommendUserApi.todayBest(UserHolder.getUserId());

        //2 查询推荐给我的用户的详情数据
        UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());

        //3 构建vo对象
        TodayBest vo = TodayBest.init(userInfo, recommendUser);

        //4 返回数据
        return vo;
    }

    public PageResult recommendation(RecommendUserDto dto) {
        //1.查询所有的推荐好友数据
        List<RecommendUser>recommendUserList=recommendUserApi.findByUserId(UserHolder.getUserId());
        //判断查询结果是否为空,如果为空,就不需要往下走了
        if (recommendUserList==null||recommendUserList.isEmpty()){
            return new PageResult(dto.getPage(),dto.getPagesize(),0,null);
        }
        //获取推荐好友的ids
//        List<Long>ids =new ArrayList<>();
//        for (RecommendUser recommendUser : recommendUserList) {
//            ids.add(recommendUser.getUserId());
//        }
        List<Long> ids = recommendUserList.stream().map(RecommendUser::getUserId)
                        .collect(Collectors.toList());

                //2.根据 推荐好友id 和查询条件 分页 查询用户详情UserInfo
        Page<UserInfo> pages =userInfoApi.findByDto(ids,dto);
        List<UserInfo> userInfoList = pages.getRecords();
        //使用流的方式,把list转为map
        // 其中key为userinfo的id(用户id)
        //value是userinfo本身
        Map<Long, UserInfo> map = userInfoList.stream()
                //toMap:转为Map key value
                .collect(Collectors.toMap(UserInfo::getId, Function.identity()));

        //3.构建Vos
        List<TodayBest> vos =new ArrayList<>();
        for (RecommendUser recommendUser : recommendUserList) {
            UserInfo userInfo = map.get(recommendUser.getUserId());
            if (userInfo!=null){
                TodayBest vo =TodayBest.init(userInfo,recommendUser);
                vos.add(vo);
            }
        }

        //4.返回分页对象
        return new PageResult(dto.getPage(),dto.getPagesize(), (int) pages.getTotal(),vos);
    }


    //根据用户id查看佳人详情
    public TodayBest personalInfo(Long userId) {
        //1、根据用户id查询，用户详情
        UserInfo userInfo = userInfoApi.findById(userId);
        //2、根据操作人id和查看的用户id，查询两者的推荐数据
      RecommendUser recommendUser=  recommendUserApi.find(userId,UserHolder.getUserId());
        //3、构造vo对象
        TodayBest vo = TodayBest.init(userInfo,recommendUser);
        //记录访客信息
        Visitors visitors  = new Visitors();
        visitors.setUserId(userId);
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitDate(DateUtil.format(new Date(),"yyyyMMdd"));
        visitorsApi.save(visitors);

        //4.返回vo数据
        return vo;
    }

    //查询用户陌生人问题
    public String strangerQuestions(Long userId) {
        //1.根据用户id查询陌生人问题
        Question question = questionApi.findById(userId);
        //2.判断陌生人问题是否为空,为空指定默认稳定
        String text = question ==null?"你喜欢java吗?":question.getTxt();
        //3.返回结果
        return text;
    }


    //回复陌生人问题
    public void replyQuestions(Long userId, String reply) {
        //1.根据用户id查询用户详情
        UserInfo userInfo = userInfoApi.findById(UserHolder.getUserId());

        //2.根据消息格式的要求,封装消息数据
        Map map = new HashMap();
        map.put("userId",UserHolder.getUserId());
        map.put("huanXinId", Constants.HX_USER_PREFIX+UserHolder.getUserId());
        map.put("nickname",userInfo.getNickname());
        map.put("strangerQuestion",strangerQuestions(userId));
        map.put("reply",reply);
        String json =JSON.toJSONString(map);

        //3.发送消息
        huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId,json);
    }

        @Value("${tanhua.default.recommend.users}")
        private List<Long> userIds;
    //实现探花的左滑右滑 数据查询
    public List<TodayBest> queryCardsList() {
        //1.查询推荐好友 随机获取10个推荐好友
        List<RecommendUser> recommendUserList=recommendUserApi.queryCardsList(UserHolder.getUserId());
        //2.判断是否查询到数据
        if (CollUtil.isEmpty(recommendUserList)){
            recommendUserList =new ArrayList<>();
            // 如果没有查询到数据,使用默认的推荐用户
            for (Long userId : userIds) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(userId);
                recommendUser.setToUserId(UserHolder.getUserId());
                recommendUser.setScore(RandomUtil.randomDouble(60,90));
                recommendUserList.add(recommendUser);
            }
        }

        //3.根据推荐用户的ids查询用户的详情 userInfo
        List<Long> ids = recommendUserList.stream()
                .map(RecommendUser::getUserId).collect(Collectors.toList());
        Map<Long, UserInfo> map = userInfoApi.findByIds(ids).stream()
                .collect(Collectors.toMap(UserInfo::getId, Function.identity()));
        //4.封装vos
        List<TodayBest> vos = new ArrayList<>();
        for (RecommendUser recommendUser : recommendUserList) {
            UserInfo userInfo = map.get(recommendUser.getUserId());
            if (userInfo!=null){
                TodayBest vo = TodayBest.init(userInfo, recommendUser);
                vos.add(vo);
            }
        }
        //返回数据
        return vos;
    }

    //喜欢
    public void likeUser(Long likeUserId) {
        //1.保存喜欢数据
       boolean  save = userLikeApi.save(UserHolder.getUserId(),likeUserId,true);
       //如果保存失败 抛异常
        if (!save){
            throw new RuntimeException("保存喜欢数据失败");
        }
        //2.保存redis缓存数据
        //添加喜欢set数据
        redisTemplate.opsForSet()
                .add(Constants.USER_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
        //删除不喜欢的set数据
        redisTemplate.opsForSet()
                .remove(Constants.USER_NOT_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());

        //3.是否是双向喜欢,如果是双向喜欢,加好友
        Boolean member = redisTemplate.opsForSet()
                .isMember(Constants.USER_LIKE_KEY + likeUserId, UserHolder.getUserId().toString());
        if (member){
            friendApi.save(UserHolder.getUserId(),likeUserId);
        }
    }
    //不喜欢
    public void notLikeUser(Long likeUserId) {
        //1.保存不喜欢数据
        boolean  save = userLikeApi.save(UserHolder.getUserId(),likeUserId,false);
        //2.保存redis缓存数据
        if (!save){
            throw new RuntimeException("保存不喜欢数据失败");
        }
        //添加不喜欢set数据
        redisTemplate.opsForSet()
                .add(Constants.USER_NOT_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());

        //删除喜欢的set数据
        redisTemplate.opsForSet()
                .remove(Constants.USER_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
        //3.是否是双向不喜欢,如果是双向喜欢,删除好友(双向删除)
        Boolean member = redisTemplate.opsForSet()
                .isMember(Constants.USER_NOT_LIKE_KEY + likeUserId, UserHolder.getUserId().toString());
        if (member){
            messagesService.deleteContacts(likeUserId);
        }
    }


    //搜附近
    public List<NearUserVo> queryNearUser(String gender, String distance) {
        //1 搜索当前操作用户，指定距离的附近的人
        List<Long> ids = userLocationApi.queryNearUser(UserHolder.getUserId(), Double.parseDouble(distance));

        //2 判断结果是否为空，为空直接返回
        if (CollUtil.isEmpty(ids)) {
            return null;
        }

        //3 根据附近的人的ids查询用户详情，根据性别进行查询
        List<UserInfo> userInfoList = userInfoApi.findByIds(ids, gender);

        //4 封装vos
        List<NearUserVo> vos = new ArrayList<>();
        for (UserInfo userInfo : userInfoList) {
            //排除我自己
            if (userInfo.getId() == UserHolder.getUserId()) {
                continue;
            }

            NearUserVo vo = NearUserVo.init(userInfo);
            vos.add(vo);
        }

        //5 返回数据
        return vos;
    }
}
